package com.project.persistence.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import com.project.bean.Features;
import com.project.bean.Role;
import com.project.persistence.db.Connect;

public class RoleDAOImpl extends AbstractDAO<Role>{
	
	@Override
	public List<Role> getAll() {
		Connect connect = new Connect();
		List<Role> roles = new ArrayList<Role>();
		Connection conn = null;
		try {

			conn = connect.getConnection();
			Statement st = conn.createStatement();
			ResultSet rs = st.executeQuery(getRolesQuery());

			while(rs.next()) {

				Role role  = new Role();
				role.setRoleId(rs.getInt("id"));
				role.setRoleName(rs.getString("name"));
				role.setRoleDescription(rs.getString("description"));
				role.setActive(rs.getBoolean("active"));

				roles.add(role);

			}

		} catch (Exception ex) {
			//TODO acrescentar error no log
			ex.printStackTrace();
		} finally {
			connect.closeConnection();
		}

		return roles;
	}
	
	@Override
	public Boolean insertObject(Role role, Connection conn) throws SQLException {

		PreparedStatement pstm = conn.prepareStatement(getInserQuery(), Statement.RETURN_GENERATED_KEYS);

		pstm.setString(1, role.getRoleName());
		pstm.setString(2, role.getRoleDescription());
		pstm.executeUpdate();
		
		ResultSet rs = pstm.getGeneratedKeys();
		
		if(rs.next()) {
			int id = rs.getInt(1);

			for (Features feature : role.getFeatures()) {
				pstm = conn.prepareStatement(getInsertRolesFeaturesQuery());
				pstm.setInt(1, id);
				pstm.setInt(2, feature.getFeatureId());
				pstm.execute();
			}
		}

		return Boolean.TRUE;

	}
	
	@Override
	public List<Role> getAllById(Integer id) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Boolean disableObject(Role r, Connection conn) throws SQLException {

		PreparedStatement pstm = conn.prepareStatement(getEnableDisableQuery());
		
		pstm.setInt(1, 0);
		pstm.setInt(2, r.getRoleId());

		return !pstm.execute();
	}
	
	@Override
	public Boolean enableObject(Role r, Connection conn) throws SQLException {
		
		PreparedStatement pstm = conn.prepareStatement(getEnableDisableQuery());
		
		pstm.setInt(1, 1);
		pstm.setInt(2, r.getRoleId());

		return !pstm.execute();
	}
	
	@Override
	public Boolean updateObject(Role r, Connection conn) throws SQLException {
		
		PreparedStatement pstm = conn.prepareStatement(getUpdateQuery());

		pstm.setString(1, r.getRoleName());
		pstm.setString(2, r.getRoleDescription());
		pstm.setInt(3, r.getRoleId());

		if (!pstm.execute()) {
			pstm = conn.prepareStatement(getClearFeaturesQuery());
			pstm.setInt(1, r.getRoleId());
			if (!pstm.execute()) {
				for (Features feature : r.getFeatures()) {
					pstm = conn.prepareStatement(getInsertRolesFeaturesQuery());
					pstm.setInt(1, r.getRoleId());
					pstm.setInt(2, feature.getFeatureId());
					pstm.execute();
				}
			}
		}
		
		return Boolean.TRUE;
	}

	@Override
	public Role getObject(Role t) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Role parseObjectFromRs(ResultSet rs) {
		// TODO Auto-generated method stub
		return null;
	}
	
	private String getRolesQuery() {
		return "SELECT * FROM roles;";
	}

	private String getInserQuery() {
		return "INSERT INTO roles (name, description, active) values ( ? , ? , 1 );";
	}

	public String getInsertRolesFeaturesQuery() {
		return "INSERT INTO roles_features (id_role, id_feature) VALUES ( ? , ? );";
	}
	
	private String getEnableDisableQuery() {
		return "UPDATE roles SET active = ? WHERE id = ?";
	}
	
	private String getUpdateQuery() {
		return "UPDATE roles SET name = ?, description = ?, active = 1 WHERE id = ?";
	}
	
	private String getClearFeaturesQuery(){
		return "DELETE FROM roles_features WHERE id_role = ?";
	}
	
}
